package inseniarlingua.trans.en_ia

import java.util.List;

import groovy.transform.CompileStatic;
import inseniarlingua.lang.Phrase;
import inseniarlingua.lang.TransPair;
import inseniarlingua.lang.en.TokenizerEN;

//@CompileStatic
class Sentence {
	def transMap
	def origSource
	List<TransPair> transPairs
	def isCapitalized = false 
	
	def join(List<?> words) {
		words = new ArrayList(words)
		StringBuilder sb = new StringBuilder()
		for (w in words) {
			if (w == null) continue
			if (sb.size() > 0 && (! (w in ['!',',']))) sb.append(' ')
			sb.append(w)
		}
		return sb.toString()
	}

	def tokenize(text) {
		TokenizerEN tokenizer = new TokenizerEN();
		tokenizer.transMap = transMap
		tokenizer.text = text
		def ret = tokenizer.tokenize();
		//def ret = text.split(' ')
		return ret
	}
	
	void setOrigSource(origSource) {
		this.origSource = origSource
		isCapitalized = Character.isUpperCase(origSource.charAt(0))
		def sourceWords = tokenize(origSource)
		transPairs = []
		for (sw in sourceWords) {
			transPairs << new TransPair(sw.toString(), null)
		}
	}
	
	def transReg(Phrase srcPhrase) {
		//println srcPhrase
		def ret = null
		Translator.getTransRegExes().each { Phrase src, Phrase trg ->
			if (src == srcPhrase) {
				def trgWords = []
				for (i in 0..<srcPhrase.groups.size()) {
					def tw = trg.groups[i]
					def spw = srcPhrase.groups[i]
					if (src.groups[i] == '*') {
						Sentence twSentence = new Sentence()
						twSentence.transMap = transMap
						twSentence.origSource = spw
						twSentence.translate()
						trgWords << twSentence.translation
					}
					else {
						trgWords << tw
					}
				}
				ret = join(trgWords)
				return
			}
		}
		return ret
	}
	
	void translate(int nwords) {
		//println "nwords=$nwords"
		//for (int i=0; i<transPairs.size()-nwords; i++) {
		int iend = transPairs.size()-nwords
		if (iend < 0) return
		for (i in 0..iend) {
			TransPair tp = transPairs[i]
			if (tp == null) continue // Empty space after translation
			if (tp.target) continue // Already translated
			
			//println "transPairs=$transPairs"
			//println "i=$i"
			def srcWords = transPairs.subList(i, i+nwords)*.source
			def srcPhrase = join(srcWords)
			def trgPhrase = transMap[srcPhrase]
			if (trgPhrase == null) {
				Phrase sp = new Phrase(srcWords)
				trgPhrase = transReg(sp)
			}
			//println "$srcPhrase --> $trgPhrase"
			if (trgPhrase != null) {
				tp.source = srcPhrase
				tp.target = trgPhrase
				def jbeg = i+1
				def jend = i+nwords
				for (j in jbeg..<jend) {
					transPairs[j] = null
				}
			}
		}
		transPairs = transPairs.findAll { it }
	}
	
	void translate() {
		def nmax = Math.min(6, transPairs.size())
		for (n in nmax..1) {
			translate(n)
		}
		wordFusionOnTarget()
	}
	
	static class FusionWords {
		List<String> fromWords
		String toWord
		FusionWords(List<String> fromWords, String toWord) {
			super();
			this.fromWords = fromWords;
			this.toWord = toWord;
		}
	}
	
	void wordFusionOnTarget() {
		final fusionWords = [new FusionWords(['de', 'le'], 'del')]
		for (fusionWord in fusionWords) {
			for(int i in 1..<transPairs.size()) {
				final tp = transPairs[i]
				if (tp.target && fusionWord.fromWords[0] == transPairs[i-1].target && fusionWord.fromWords[1] == tp.target) {
					transPairs[i-1].source += " " + tp.source
					transPairs[i-1].target = fusionWord.toWord
					transPairs.remove(i)
					int count = transPairs.size()
					return // TODO Need to consider more contractions
				}
			}
		}
	}
	
	def getTranslation() {
		for (tp in transPairs) {
			if (tp.target == null) {
				if (tp.source.charAt(0).isUpperCase()) {
					tp.target = tp.source					
				}
				else {
					tp.target = "*${tp.source}*".toString()
				}
			}
		}  
		def ret = join(transPairs*.target)
//		if (isCapitalized) {
//			ret = ret.capitalize()
//		}
		return ret
	} 
}
